#include <ximera/gui/cegui/inputhandler.hpp>
#include <ximera/gui/cegui/cegui.hpp>

#include <CEGUISystem.h>

namespace ximera { namespace gui { namespace cegui
{
    InputHandler::InputHandler(system::Application& app)
        : app(app)
    {
        _mouseMove = app.inputSystem()->mouse()->onAxisChange() += boost::bind(&InputHandler::onMouseMove, this, _1, _2, _3, _4, _5);
        _mouseDown = app.inputSystem()->mouse()->onMouseDown() += boost::bind(&InputHandler::onMouseDown, this, _1, _2);
        _mouseUp = app.inputSystem()->mouse()->onMouseUp() += boost::bind(&InputHandler::onMouseUp, this, _1, _2);
        _keyDown = app.inputSystem()->keyboard()->onKeyDown() += boost::bind(&InputHandler::onKeyDown, this, _1, _2);
        _keyUp = app.inputSystem()->keyboard()->onKeyUp() += boost::bind(&InputHandler::onKeyUp, this, _1, _2);
    }

    InputHandler::~InputHandler()
    {
        _mouseMove.disconnect();
        _mouseDown.disconnect();
        _mouseUp.disconnect();
        _keyDown.disconnect();
        _keyUp.disconnect();
    }

    void InputHandler::onMouseMove(input::IDevice* sender, Byte axisIndex, Real lastValue, Real newValue, Real relValue)
    {
        Real deltaX = 0, deltaY = 0;

        if (axisIndex == 0)
            deltaX = relValue;
        else if (axisIndex == 1)
            deltaY = relValue;

        CEGUI::System::getSingleton().injectMouseMove(deltaX, deltaY);
    }

    void InputHandler::onMouseDown(input::IMouse* sender, input::MouseCode const& mouseCode)
    {
        CEGUI::System::getSingleton().injectMouseButtonDown(ximeraToCEGui(mouseCode));
    }

    void InputHandler::onMouseUp(input::IMouse* sender, input::MouseCode const& mouseCode)
    {
        CEGUI::System::getSingleton().injectMouseButtonUp(ximeraToCEGui(mouseCode));
    }

    void InputHandler::onKeyDown(input::IKeyboard* sender, input::KeyCode const& keyCode)
    {
        Char ch = keyCodeToChar(keyCode);
        if (ch != 0)
            CEGUI::System::getSingleton().injectChar(ch);

        CEGUI::System::getSingleton().injectKeyDown(static_cast<CEGUI::uint>(keyCode));
    }

    void InputHandler::onKeyUp(input::IKeyboard* sender, input::KeyCode const& keyCode)
    {
        CEGUI::System::getSingleton().injectKeyUp(static_cast<CEGUI::uint>(keyCode));
    }
}}}
